using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Reflection;

namespace PackTracker.Mobile.Negocio
{
    /// <summary>
    /// Manage application configuration
    /// </summary>
    public class Configuration : IDisposable
    {
        private const string CONFIG_FILE_NAME = "SmartConfig.xml"; //Configuration file name
        
        private string configurationFilePath = string.Empty; //Full path to configuration file

        private Dictionary<string, string> configurations; //Configuration dictionary

        /// <summary>
        /// Load configuration file into a configuration dictionay.
        /// </summary>
        public Configuration()
        {
            //Get directori of application
            FileInfo file = new FileInfo(Assembly.GetExecutingAssembly().GetName().CodeBase);

            //Get configuration file path
            this.configurationFilePath = Path.Combine(file.DirectoryName, CONFIG_FILE_NAME);

            XmlDocument configFile = new XmlDocument();
            configFile.Load(this.configurationFilePath);
            //Get all configurations
            XmlNodeList configs = configFile.SelectNodes("//add");

            this.configurations = new Dictionary<string, string>();

            //Populate configuration dictionary
            foreach (XmlElement config in configs)
            {
                if (!this.configurations.ContainsKey(config.GetAttribute("key")))
                    this.configurations.Add(config.GetAttribute("key"), config.GetAttribute("value"));
            }
        }

        /// <summary>
        /// Set configuration value. If configuration key does not exists, a new key is generated.
        /// </summary>
        /// <param name="key">Configuration Name</param>
        /// <param name="value">Configuration Value</param>
        public void SetConfig(string key, string value)
        {
            if (!this.configurations.ContainsKey(key))
                this.configurations.Add(key, value);
            else
                this.configurations[key] = value;
        }

        /// <summary>
        /// Get configuration value
        /// </summary>
        /// <param name="key">Configuration Name</param>
        /// <returns>Configuration Value</returns>
        public string GetConfig(string key)
        {
            return this.configurations[key];
        }

        /// <summary>
        /// Persist memory settings into settings file
        /// </summary>
        public void Dispose()
        {
            XmlDocument configFile = new XmlDocument();
            configFile.Load(this.configurationFilePath);

            foreach (KeyValuePair<string, string> config in this.configurations)
            {
                //Get configuration note based on configuration name
                XmlElement configNode = (XmlElement)configFile.SelectSingleNode(string.Format("//add[@key = '{0}']", config.Key));

                //If not exists
                if (configNode == null)
                {
                    //Create configuration note
                    configNode = configFile.CreateElement("add");
                    configNode.SetAttribute("key", config.Key);
                    configNode.SetAttribute("value", config.Value);

                    configFile.SelectSingleNode("//appSettings").AppendChild(configNode);
                }
                else
                {
                    //Update configuration value
                    configNode.SetAttribute("value", config.Value);
                }
            }

            //Save configuration file
            configFile.Save(this.configurationFilePath);
        }

    }
}
